import axios from "axios";
import Utils from "./Utils";
import qs from "qs";
import JSONBig from "json-bigint";
import { ElMessage } from "element-plus";
import { useUserStoreHook } from "/@/store/modules/user";
import prompt from "/@/common/promptEnum";
import { loadEnv } from "@build/index";

export interface IResult {
  code: number;
  data?: any;
  msg?: string;
}

// @ts-ignore
const { VITE_PROXY_DOMAIN, VITE_PROXY_DOMAIN_REAL, MODE } = loadEnv();

export const getURL = (url?: string): string => {
  if (url) {
    if (url.startsWith("http")) {
      return url;
    } else {
      if (MODE === "development") {
        return VITE_PROXY_DOMAIN + url;
      } else {
        return VITE_PROXY_DOMAIN_REAL + url;
      }
    }
  } else {
    if (MODE === "development") {
      return VITE_PROXY_DOMAIN;
    } else {
      return VITE_PROXY_DOMAIN_REAL;
    }
  }
};

const service = axios.create({
  baseURL: getURL(), // url = base url + request url
  timeout: 30000,
  withCredentials: true // send cookies when cross-domain requests
});

// Request interceptors
service.interceptors.request.use(
  config => {
    if (config.method === "post" || config.method === "put") {
      config.data = qs.stringify(Utils.exceptNull(config.data));
    } else {
      config.params = Utils.exceptNull(config.params);
    }
    config.headers["Content-Type"] = "application/x-www-form-urlencoded";
    // Add X-Access-Token header to every request, you can add other custom headers here
    if (useUserStoreHook().$state.token) {
      config.headers["X-Access-Token"] = useUserStoreHook().$state.token;
    }
    return config;
  },
  error => {
    console.log(error, prompt.ERROR);
    Promise.reject(error);
  }
);

service.defaults.transformResponse = [
  (data: any) => {
    if (data.includes("<!DOCTYPE html>") || data.includes("login error")) {
      return JSON.stringify(data);
    }
    return JSONBig.parse(data);
  }
];

// Response interceptors
service.interceptors.response.use(
  response => {
    if (response.status === 401) {
      useUserStoreHook().logOut();
    }
    if (response.data.code === 4) {
      ElMessage.error(response.data.msg);
    } else if (response.data.code !== 3) {
      return response;
    } else {
      if (VITE_PROXY_DOMAIN) {
        useUserStoreHook().logOut();
      } else {
        // UserModule.ResetToken();
        useUserStoreHook().logOut();
        // router.push("/");
      }
    }
  },
  error => {
    console.log("error");
    console.log(error);
    console.log(JSON.stringify(error));
    return Promise.reject(error);
  }
);

export interface IRequest<T = any> {
  url: string;
  params?: T;
  parentUrl?: string;
}

export const $post = ({
  url,
  params,
  parentUrl
}: IRequest): Promise<IResult> => {
  if (parentUrl) {
    url = parentUrl + url;
  }
  return service.post(url, params).then(ref => {
    return ref.data;
  });
};

export const $get = ({
  url,
  params,
  parentUrl
}: IRequest): Promise<IResult> => {
  if (parentUrl) {
    url = parentUrl + url;
  }
  return service.get(url, { params }).then(ref => {
    return ref.data;
  });
};

export const $patch = ({
  url,
  params,
  parentUrl
}: IRequest): Promise<IResult> => {
  if (parentUrl) {
    url = parentUrl + url;
  }
  return service.patch(url, params).then(ref => {
    return ref.data;
  });
};

export const $delete = ({
  url,
  params,
  parentUrl
}: IRequest): Promise<IResult> => {
  if (parentUrl) {
    url = parentUrl + url;
  }
  return service.delete(url, { params }).then(ref => {
    return ref.data;
  });
};

export const $put = ({
  url,
  params,
  parentUrl
}: IRequest): Promise<IResult> => {
  if (parentUrl) {
    url = parentUrl + url;
  }
  return service.put(url, params).then(ref => {
    return ref.data;
  });
};

export default service;
